home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Tool Chest / Dev.CD Feb 97 TC.toast / Sample Code / Development Tools & Languages / AppsToGo / DTS.Lib / Preferences.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-22  |  6.5 KB  |  264 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** File:        Preferences.c
  5. ** Written by:    Eric Soldan
  6. **
  7. ** Copyright © 1989-1993 Apple Computer, Inc.
  8. ** All rights reserved.
  9. */
  10.  
  11. /* You may incorporate this sample code into your applications without
  12. ** restriction, though the sample code has been provided "AS IS" and the
  13. ** responsibility for its operation is 100% yours.  However, what you are
  14. ** not permitted to do is to redistribute the source as "DSC Sample Code"
  15. ** after having made changes. If you're going to re-distribute the source,
  16. ** we require that you make it clear in the source that the code was
  17. ** descended from Apple Sample Code, but that you've made changes. */
  18.  
  19.  
  20.  
  21.  
  22. /*****************************************************************************/
  23.  
  24.  
  25.  
  26. #include "DTS.Lib2.h"
  27. #include "DTS.Lib.protos.h"
  28.  
  29. #ifndef __ERRORS__
  30. #include <Errors.h>
  31. #endif
  32.  
  33. #ifndef __FOLDERS__
  34. #include <Folders.h>
  35. #endif
  36.  
  37. #ifndef __GESTALTEQU__
  38. #include <GestaltEqu.h>
  39. #endif
  40.  
  41. #ifndef __RESOURCES__
  42. #include "Resources.h"
  43. #endif
  44.  
  45. #ifndef __TOOLUTILS__
  46. #include <ToolUtils.h>
  47. #endif
  48.  
  49. #ifndef __UTILITIES__
  50. #include "Utilities.h"
  51. #endif
  52.  
  53.  
  54.  
  55. /*****************************************************************************/
  56.  
  57.  
  58.  
  59. extern short                gAUXVersion;
  60. extern GetPreferenceProcPtr    gGetPreferenceProc;
  61.  
  62. TreeObjHndl            gPreferences;
  63. static FSSpec        gPrefsLoc = {0, 0, "\p"};
  64.  
  65.  
  66.  
  67. /*****************************************************************************/
  68. /*****************************************************************************/
  69.  
  70. #ifdef applec
  71. #pragma segment ATGPreferences
  72. #endif
  73.  
  74. /*****************************************************************************/
  75. /*****************************************************************************/
  76.  
  77.  
  78.  
  79. OSErr    ReadPreferences(OSType prefType, OSType prefCreator, short prefLocID)
  80. {
  81.     OSErr            err;
  82.     short            res, oldRes;
  83.     long            dirID;
  84.     Str31            prefsFile;
  85.     Handle            hndl;
  86.     FInfo            finfo;
  87.  
  88.     gGetPreferenceProc = GetPreference;
  89.         /* Prevent dead-stripping if ReadPreferences is called.  If thisis called,
  90.         ** the application is committing to preferences. */
  91.  
  92.     GetIndString(gPrefsLoc.name,  prefLocID, 1);
  93.     GetIndString(prefsFile,       prefLocID, 2);
  94.         /* Get the application's preference folder/file names to create/open. */
  95.  
  96.     if (gSystemVersion >= 0x0700)
  97.         err = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder,
  98.                          &gPrefsLoc.vRefNum, &gPrefsLoc.parID);
  99.     else
  100.         err = FindSysFolder(&gPrefsLoc.vRefNum, &gPrefsLoc.parID);
  101.  
  102.     if (!err) {
  103.         err = DirCreate(gPrefsLoc.vRefNum, gPrefsLoc.parID, gPrefsLoc.name, &dirID);
  104.         if (err == dupFNErr) err = noErr;
  105.     }
  106.  
  107.     if (!err) {
  108.         oldRes = CurResFile();
  109.  
  110.         BlockMove(gPrefsLoc.name + 1, gPrefsLoc.name + 2, gPrefsLoc.name[0]++);
  111.         gPrefsLoc.name[1] = (gAUXVersion) ? '/' : ':';
  112.         pcatchr(gPrefsLoc.name, gPrefsLoc.name[1], 1);
  113.         pcat   (gPrefsLoc.name, prefsFile);
  114.  
  115.         HCreateResFile(gPrefsLoc.vRefNum, gPrefsLoc.parID, gPrefsLoc.name);
  116.         err = ResError();
  117.         if (!err) {
  118.             err = HGetFInfo(gPrefsLoc.vRefNum, gPrefsLoc.parID, gPrefsLoc.name, &finfo);
  119.             if (!err) {
  120.                 finfo.fdType    = prefType;
  121.                 finfo.fdCreator = prefCreator;
  122.                 err = HSetFInfo(gPrefsLoc.vRefNum, gPrefsLoc.parID, gPrefsLoc.name, &finfo);
  123.             }
  124.         }
  125.         if (err == dupFNErr) err = noErr;
  126.         if (err) {
  127.             UseResFile(oldRes);
  128.             return(err);
  129.         }
  130.  
  131.         SetResLoad(false);
  132.         res = HOpenResFile(gPrefsLoc.vRefNum, gPrefsLoc.parID, gPrefsLoc.name, fsRdPerm);
  133.         err = ResError();
  134.         SetResLoad(true);
  135.         if (err) {
  136.             UseResFile(oldRes);
  137.             return(err);
  138.         }
  139.  
  140.         gPreferences = NewRootObj(ROOTOBJ, 0);
  141.         if (!gPreferences) {
  142.             CloseResFile(res);
  143.             UseResFile(oldRes);
  144.             return(memFullErr);
  145.         }
  146.  
  147.         UseResFile(res);
  148.         hndl = GetResource('aprf', 128);
  149.         if (!hndl) {
  150.             CloseResFile(res);
  151.             UseResFile(oldRes);
  152.             return(resNotFound);
  153.         }        /* Read in file's preference resource.  If it doesn't exist in the pref's file,
  154.                 ** then it is gotten out of the app.  If it doesn't exist there,then return an
  155.                 ** error.  The app should resolve this by creating the default preference info. */
  156.  
  157.         DetachResource(hndl);
  158.         CloseResFile(res);
  159.         UseResFile(oldRes);
  160.  
  161.         err = HReadTree(gPreferences, hndl);
  162.             /* Note that you CAN save preference data in the root object, since the min size
  163.             ** of the root object is determined by the app (in File.c).  However, the
  164.             ** convention for the preference hierarchy is to have a dumb root object, and
  165.             ** then hang objects off of the root of type APRFOBJ.  The APRFObj contains the
  166.             ** window state data, and this data will be managed automatically by the framework
  167.             ** (if a document of the OSType indicated by the APRFObj is opened, for example).
  168.             ** The APRFObj data area is therefore off limits to the application.  HOWEVER,
  169.             ** there is no restriction to adding children to the APRFObj.  The children of
  170.             ** the APRFObj can be of any type you want.  Therefore application-specific
  171.             ** preference data should be saved below the APRFObj level. */
  172.  
  173.         DisposeHandle(hndl);
  174.     }
  175.  
  176.     return(err);
  177. }
  178.  
  179.  
  180.  
  181. /*****************************************************************************/
  182.  
  183.  
  184.  
  185. OSErr    WritePreferences(void)
  186. {
  187.     short    oldRes, res;
  188.     Handle    hndl;
  189.     OSErr    err;
  190.  
  191.     oldRes = CurResFile();
  192.     SetResLoad(false);
  193.     res = HOpenResFile(gPrefsLoc.vRefNum, gPrefsLoc.parID, gPrefsLoc.name, fsRdWrPerm);
  194.     err = ResError();
  195.     SetResLoad(true);
  196.     if (err) {
  197.         UseResFile(oldRes);
  198.         return(err);
  199.     }
  200.  
  201.     UseResFile(res);
  202.     hndl = GetResource('aprf', 128);
  203.     if (hndl) {
  204.         RemoveResource(hndl);
  205.         DisposeHandle(hndl);
  206.     }
  207.  
  208.     if (gPreferences) {
  209.         hndl = NewHandle(0);
  210.         if (hndl) {
  211.             err = HWriteTree(gPreferences, hndl);
  212.             if (!err) {
  213.                 AddResource(hndl, 'aprf', 128, nil);
  214.                 ChangedResource(hndl);
  215.                 WriteResource(hndl);
  216.                 DetachResource(hndl);
  217.             }
  218.             DisposeHandle(hndl);
  219.         }
  220.     }
  221.  
  222.     CloseResFile(res);
  223.     UseResFile(oldRes);
  224.  
  225.     return(err);
  226. }
  227.  
  228.  
  229.  
  230. /*****************************************************************************/
  231.  
  232.  
  233.  
  234. TreeObjHndl    GetPreference(OSType prefType, Boolean *newPref)
  235. {
  236.     short        i;
  237.     TreeObjHndl    cobj;
  238.  
  239.     if (newPref) *newPref = false;
  240.  
  241.     if (!gPreferences) return(nil);
  242.         /* Shouldn't ever happen if ReadPreferences was called. (See ReadPreferences.) */
  243.  
  244.     for (i = (*gPreferences)->numChildren; i;) {
  245.         cobj = GetChildHndl(gPreferences, --i);
  246.         if (mDerefAPRF(cobj)->sfType == prefType) return(cobj);
  247.     }
  248.  
  249.     if (!newPref) return(nil);
  250.         /* We only automatically create one if we are passed a pointer to indicate if
  251.         ** the preference returned is new.  This way newPref can also serve as a flag. */
  252.  
  253.     cobj = NewChild(NO_EDIT, gPreferences, -1, APRFOBJ, sizeof(APRFObj));
  254.     if (cobj) {
  255.         mDerefAPRF(cobj)->sfType = prefType;
  256.         *newPref = true;
  257.     }
  258.  
  259.     return(cobj);
  260. }
  261.  
  262.  
  263.  
  264.